Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite.rs: refactor new_parents to depend only on parent_mapping #2646

Merged
merged 1 commit into from
Dec 13, 2023

Conversation

ilyagr
Copy link
Contributor

@ilyagr ilyagr commented Nov 28, 2023

PR Notes

This could be reviewed now or together with the other refactors that would happen in subsequent commits (making new_parents a public function, etc). If you prefer the latter, let me know. You can also look at https://github.com/ilyagr/jj/tree/refactor, but it's still
unpolished.

I'm posting this mainly to illustrate my plans, and so that you can let me know if there is some fatal problem with them.


Commit description

Previously, the function relied on both the self.parent_mapping and self.rebased. If (A,B) was in parent_mapping and (B,C) was in rebased, new_parents would map A to C.

Now, self.rebased is ignored by new_parents. In the same situation, DescendantRebaser is changed so that both (A,B) and (B,C) are in parent_mapping before. new_parents now applies parent_mapping repeatedly, and will map A to C in this situation.

Cons

  • The semantics are changed; new_parents now panics if self.parent_mapping contain cycles. AFAICT, such cycles never happen in jj anyway, except for one test that I had to fix. I think it's a sensible restriction to live with; if you do want to swap children of two commits, you can call rebase_descendants twice.

Pros

  • I find the new logic much easier to reason about. I plan to extract it into a function, to be used in refactors for jj rebase -r and jj new --after. It will make it much easier to have a correct implementation of jj rebase -r --after, even when rebasing onto a descendant.

  • The de-duplication is no longer O(n^2). I tried to keep the common case fast.

Alternatives

  • We could make jj rebase and jj new use a separate function with the algorithm shown here, without changing DescendantRebaser. I believe that the new algorithm makes DescendatRebaser easier to understand, though, and it feels more elegant to reduce code duplication.

  • The de-duplication optimization here is independent of other changes, and could be used on its own.

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added tests to cover my changes

@ilyagr ilyagr marked this pull request as ready for review November 28, 2023 00:52
@ilyagr ilyagr added help wanted Extra attention is needed question Further information is requested and removed help wanted Extra attention is needed labels Nov 28, 2023
@ilyagr ilyagr force-pushed the refactor1 branch 3 times, most recently from 6a6f499 to ea7f3f5 Compare November 28, 2023 03:06
@ilyagr ilyagr force-pushed the refactor1 branch 3 times, most recently from 59ef635 to 149df31 Compare November 28, 2023 07:00
lib/src/rewrite.rs Outdated Show resolved Hide resolved
lib/src/rewrite.rs Outdated Show resolved Hide resolved
lib/src/rewrite.rs Show resolved Hide resolved
@ilyagr ilyagr removed the question Further information is requested label Nov 28, 2023
@ilyagr ilyagr force-pushed the refactor1 branch 9 times, most recently from c5f1b89 to fa5fd1a Compare December 1, 2023 03:15
@ilyagr
Copy link
Contributor Author

ilyagr commented Dec 1, 2023

I added a few comments. I realized that, for other uses, the assertion that replacements are non-empty might be unnecessary, but I'm not sure when if ever other uses might come up.

ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 1, 2023
See comments inline for details.

In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646.
They don't seem to be.
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 1, 2023
See comments inline for details. Cc jj-vcs#2600.

In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646.
They don't seem to be.
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 1, 2023
See comments inline for details. Cc jj-vcs#2600.

In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646.
They don't seem to be.

The tests ended up weirder than expected because of
jj-vcs#2600 (comment). Even
though, for now, the behavior of tests is unaffected by that issue, the
*expected* behavior is different.
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 1, 2023
See comments inline for details. Cc jj-vcs#2600.

In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646.
They don't seem to be.

The tests ended up weirder than expected because of
jj-vcs#2600 (comment). Even
though, right now, the behavior of tests is unaffected by that issue, the
*expected* behavior is different.
@ilyagr ilyagr changed the title rewrite.rs: refactor new_parents to depend only on parent_mapping rewrite.rs: refactor new_parents to depend only on parent_mapping Dec 1, 2023
Copy link
Contributor

@yuja yuja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have much expertise on rebase code, but I think we agreed that the change direction is good, so I went ahead and marked as approved.

lib/src/rewrite.rs Outdated Show resolved Hide resolved
lib/src/rewrite.rs Outdated Show resolved Hide resolved
lib/tests/test_rewrite.rs Show resolved Hide resolved
ilyagr added a commit that referenced this pull request Dec 2, 2023
See comments inline for details. Cc #2600.

In particular, I wanted to make sure these behaviors are not affected by #2646.
They don't seem to be.

The tests ended up weirder than expected because of
#2600 (comment). Even
though, right now, the behavior of tests is unaffected by that issue, the
*expected* behavior is different.
@ilyagr
Copy link
Contributor Author

ilyagr commented Dec 3, 2023

I'm thinking of maybe waiting until the next release (which is, I'm guessing, planned for Wednesday) before merging this, since I doubt I'll have time to implement any user-visible bugfixes or features that use this PR before that.

@ilyagr ilyagr force-pushed the refactor1 branch 3 times, most recently from f237963 to 8dd1e63 Compare December 12, 2023 05:10
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 12, 2023
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 12, 2023
@ilyagr
Copy link
Contributor Author

ilyagr commented Dec 12, 2023

Planning to merge this in ~24 hours.

ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 12, 2023
Previously, the function relied on both the `self.parent_mapping` and
`self.rebased`. If `(A,B)` was in `parent_mapping` and `(B,C)` was in `rebased`,
`new_parents` would map `A` to `C`.

Now, `self.rebased` is ignored by `new_parents`. In the same situation,
DescendantRebaser is changed so that both `(A,B)` and `(B,C)` are in
`parent_mapping` before. `new_parents` now applies `parent_mapping` repeatedly,
and will map `A` to `C` in this situation.

## Cons

- The semantics are changed; `new_parents` now panics if `self.parent_mapping`
  contain cycles. AFAICT, such cycles never happen in `jj` anyway, except for
one test that I had to fix. I think it's a sensible restriction to live with;
if you do want to swap children of two commits, you can call
`rebase_descendants` twice.

## Pros

- I find the new logic much easier to reason about. I plan to extract it into a
function, to be used in refactors for `jj rebase -r` and `jj new --after`. It
will make it much easier to have a correct implementation of `jj rebase -r
--after`, even when rebasing onto a descendant.

- The de-duplication is no longer O(n^2). I tried to keep the common case fast.

## Alternatives

- We could make `jj rebase` and `jj new` use a separate function with the
algorithm shown here, without changing DescendantRebaser. I believe that the new
algorithm makes DescendatRebaser easier to understand, though, and it feels more
elegant to reduce code duplication.

- The de-duplication optimization here is independent of other changes, and
could be used on its own.
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 13, 2023
@ilyagr ilyagr enabled auto-merge (rebase) December 13, 2023 03:28
@ilyagr ilyagr merged commit 316ab8e into jj-vcs:main Dec 13, 2023
15 checks passed
@ilyagr ilyagr deleted the refactor1 branch December 13, 2023 03:35
ilyagr added a commit to ilyagr/jj that referenced this pull request Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants